﻿#include "widget.h"
#include "ui_widget.h"
#include "appconfig.h"

#include <QHostInfo>
#include <QHostAddress>
#include <QDebug>
#include <QDateTime>
#include <QMessageBox>
#include <QTimer>
#include <QTimer>
#include <QTextCodec>
#include <QTextCodec>

extern "C" {

int  hex_asc(unsigned char *hex,unsigned char *asc,int hexlength)
{
    unsigned char  hLowbit=0,hHighbit=0;
    int i;
    for(i=0;i<hexlength*2;i=i+2)
    {
        hLowbit=hex[i/2]&0x0f;
        hHighbit=hex[i/2]/16;
        if(hHighbit>=10)
            asc[i]=hHighbit+'7';
        else
            asc[i]=hHighbit+'0';

        if(hLowbit>=10)
            asc[i+1]=hLowbit+'7';
        else
            asc[i+1]=hLowbit+'0';
    }
    asc[hexlength*2]='\0';
    return 0;
}


int  asc_hex(unsigned char *asc, unsigned char *hex, int pair_len)
{
    char src1,src2;
    int len;

    for (len=0; len < pair_len; len++)
    {
        src1 = *(asc+len*2);
        src2 = *(asc+len*2+1);
        if ((src1>='0') && (src1<='9'))
            src1=src1-'0';
        else if ((src1>='A') && (src1<='F'))
            src1=src1-'A'+10;
        else if ((src1>='a') && (src1<='f'))
            src1=src1-'a'+10;
        else
            return -1;

        if ((src2>='0') && (src2<='9'))
            src2=src2-'0';
        else if ((src2>='A') && (src2<='F'))
            src2=src2-'A'+10;
        else if ((src2>='a') && (src2<='f'))
            src2=src2-'a'+10;
        else
            return -1;

        *hex++ = (src1 << 4) | src2;
    }
    return 0;
}
}
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);    
   // connect(this, SIGNAL(&QTabWidget::currentChanged(int)), this, SLOT(&Widget::on_tabWidget_currentChanged(int)));
    InitUI();
    InitConnectSignals();
}

Widget::~Widget()
{
    AppController::Destroy();
    delete ui;
}

void Widget::InitUI()
{
    AppConfig* config = AppConfig::Instance();
    if (config == nullptr)
        return;
    //设置home图标
    QPixmap pixmap(":/udpCast/Res/HomePic.png");
    ui->label_ClientOrServer->setPixmap(pixmap);
    ui->tabWidget->setCurrentIndex(0); //默认第一个broadcast
    //获取本机IP地址
    ui->lEdit_LocalAddr->setText(config->LocalIP());
    //广播端口号
    ui->lEdit_TargetPort->setText(QString::number(config->BroadCastPort()));
    //广播目标地址
    ui->lEdit_BroadcastAddr->setText(config->BroadCastIP());
    ui->lEdit_TargetAddr->setText(config->BroadCastIP());
    //ui->lEdit_TargetAddr->setReadOnly(true); lineedit不可修改，但内容不变成灰色
    ui->lEdit_TargetAddr->setFocusPolicy(Qt::NoFocus);// lineedit不可修改，但内容不变成灰色
    ui->lEdit_TargetAddr->setStyleSheet("background:transparent;border-width:0;border-style:outset");//lineedit不显示边框
    ui->lEdit_TargetPort->setEnabled(false);//lineedit不可修改，内容变成灰色
    ui->lEdit_TargetPort->setStyleSheet("background:transparent;border-width:0;border-style:outset");
    ui->checkBox_IsStopDispRecv->setCheckState(Qt::Unchecked);
    ui->tEdit_Recv->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    ui->tEdit_Send->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    //以下初始化组播默认参数
    ui->lEdit_localIP_muticast->setText(config->LocalIP());
    //ui->lEdit_localIP_muticast->setReadOnly(true);
    ui->lEdit_localPort_muticast->setText(QString::number(config->localPort_Muticast()));
    ui->lEdit_muticastAddr->setText(config->MutiCastIP());
    ui->lEdit_muticastAddr->setEnabled(false); //lineeidt不可修改，内容变灰色
    ui->lEdit_muticastAddr->setStyleSheet("background:transparent;border-width:0;border-style:outset");//不显示边框
    ui->chkBox_ifStopdispRecv_muticast->setCheckState(Qt::Unchecked);
    ui->lEdit_TargetAddr_muticast->setText(config->MutiCastIP());
    ui->lEdit_TargetPort_muticast->setText(QString::number(config->MutiCastPort()));
    ui->tEdit_Recv_muticast->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    ui->tEdit_Send_Muticast->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    //以下初始化点播默认参数
    ui->lEdit_localAddr_unicast->setText(config->LocalIP());
    ui->lEdit_localPort_unicast->setText(QString::number(config->LocalPort_UniCast()));
    ui->lEdit_TargetIpAddr_unicast->setText(config->TargetIP_UniCast());
    ui->lEdit_TargetPort_unicast->setText(QString::number(config->TargetPort_UniCast()));
    ui->tEdit_Recv_unicast->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    ui->tEdit_Send_unicast->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
}

void Widget::InitConnectSignals()
{
    AppController* controller = AppController::Instance();

    if (nullptr == controller)
        return;
    myTimer = new QTimer;
    if(myTimer != nullptr){
        connect(myTimer, &QTimer::timeout, this, &Widget::OnAutoSendData);
    }

    connect(controller, SIGNAL(ReceiveData(QByteArray&)), this, SLOT(OnReceiveData(QByteArray&)));
    connect(this,&Widget::tabChanged, controller, &AppController::ResetController);
   // connect(this, &Widget::tabChanged, this, &Widget::InitUI);

}


void Widget::on_tabWidget_currentChanged(int index)
{
    qDebug() << "index=%d" << index;
    emit tabChanged(index);
    AppConfig *config = AppConfig::Instance();
    if(config == nullptr){
        return;
    }
    ui->label_ClientOrServer->setText("");
     // 在这里根据index处理不同的UI逻辑
    switch(index){
    case 0:
        qDebug() << "enter broadcast switch";
        config->setCastType(BroadCast_type);

        break;
    case 1:
         qDebug() << "enter muticast switch";
         config->setCastType(MutiCast_type);
        break;
    case 2:
         qDebug() << "enter unicast switch";
         config->setCastType(UniCast_type);
#if _UNICAST_SERVER
         ui->label_ClientOrServer->setText(QString("点播服务器"));
#else
         ui->label_ClientOrServer->setText(QString("点播客户端"));
#endif
        break;
    default:
        qDebug() << "para error";
        return;
    }
}





void Widget::on_pBtn_Start_clicked()
{

    AppController* controller = AppController::Instance();

    if (nullptr == controller)
        return;

    QString btnState = ui->pBtn_Start->property("state").toString();
    qDebug() << "btnState=" << btnState;
    if (btnState.isEmpty() || btnState == "stop")
    {
        ui->pBtn_Start->setProperty("state", "start");
        ui->pBtn_Start->setText(QObject::tr("stop"));
        controller->StartController();
    }
    else
    {
        ui->pBtn_Start->setProperty("state", "stop");
        ui->pBtn_Start->setText(QObject::tr("start"));
        controller->StopController();
    }
}



void Widget::on_checkBox_IfHexRecv_stateChanged()
{
    QString dispMsg, lastRecvStr;
    QString recvStr = m_lastRecvMsg;
    qDebug() << "recvStr = " << recvStr;

    if(!recvStr.isEmpty()){
        if(ui->checkBox_IfHexRecv->checkState() == Qt::Checked){
              dispMsg = AsciiToHex(recvStr);
              lastRecvStr = QString("%1%2").arg("Last received Message(Hex):").arg(dispMsg);
        }else{
              recvStr = ui->tEdit_Send->toPlainText();
              dispMsg = HexToAscii(recvStr);
//              dispMsg = HexToAscII(recvStr);
              if(dispMsg.isEmpty()){
                 dispMsg = "error! Not a valid integer value.";
              }
              lastRecvStr = QString("%1%2").arg("Last received Message(AscII):").arg(dispMsg);
        }
        ui->tEdit_Recv->append(lastRecvStr);
    }
}

void Widget::OnReceiveData(QByteArray &data)
{
    AppConfig *config = AppConfig::Instance();
    if(config == nullptr){
        return;
    }
    switch(config->CastType()){
    case BroadCast_type:
        OnReceiveBroadCastData(data);
        break;
    case MutiCast_type:
        OnReceiveMutiCastData(data);
        break;
    case UniCast_type:
        OnReceiveUnicastData(data);
        break;
    default:
        qDebug() << "castType error" << config->CastType();
        break;
    }
}

void Widget::OnReceiveBroadCastData(QByteArray& data)
{
    QString RecvMsg;
    qDebug() << "data:" << QString::fromUtf8((const char*)data) << data<<data.length();

    if(data.isEmpty()){
        qDebug() << "recv data is empty.";
        return;
    }
    if(ui->checkBox_IsStopDispRecv->checkState() == Qt::Checked){
        return;
    }
    if(ui->checkBox_IfHexRecv->checkState() == Qt::Checked){
        RecvMsg = AsciiToHex(QString::fromUtf8((const char*)data));
    }else{
        RecvMsg = QString::fromUtf8((const char*)data);
    }
    QDateTime currentdateTime = QDateTime::currentDateTime();
    QString currentMsgstr = QString("%1%2%3").arg(currentdateTime.toString("yyyy-mm-dd hh:mm:ss")).arg(tr(" received massage: ")).arg(RecvMsg);
    qDebug() << "currentMsgstr:" << currentMsgstr;
    ui->tEdit_Recv->append(currentMsgstr);
    m_lastRecvMsg = QString::fromUtf8(data);

}

void Widget::OnReceiveMutiCastData(QByteArray &data)
{
    QString RecvMsg;

    if(data.isEmpty()){
        qDebug() << "recv data is empty.";
        return;
    }
    if(ui->chkBox_ifStopdispRecv_muticast->checkState() == Qt::Checked){
        return;
    }

    if(ui->chkBox_hex_recv_muticast->checkState() == Qt::Checked){
        RecvMsg = AsciiToHex(QString::fromUtf8((const char*)data));
    }else{
        RecvMsg = QString::fromUtf8((const char*)data);
    }

    QDateTime cuurentdateTime = QDateTime::currentDateTime();
    QString currentMsgstr = QString("%1%2%3").arg(cuurentdateTime.toString("yyyy-mm-dd hh:mm:ss")).arg(tr(" received massage: ")).arg(RecvMsg);

    ui->tEdit_Recv_muticast->append(currentMsgstr);

}

void Widget::OnReceiveUnicastData(QByteArray &data)
{
    QString RecvMsg;

    if(data.isEmpty()){
        qDebug() << "recv data is empty.";
        return;
    }

    if(ui->chkBox_IfStopDispRecv_unicast->checkState() == Qt::Checked){
        return;
    }

    if(ui->chkBox_IfHexRecv_unicast->checkState() == Qt::Checked){
        RecvMsg = AsciiToHex(QString::fromUtf8((const char*)data));
    }else{
        RecvMsg = QString::fromUtf8((const char*)data);
    }

    QDateTime currentdateTime = QDateTime::currentDateTime();
    QString currentMsgstr = QString("%1%2%3").arg(currentdateTime.toString("yyyy-mm-dd hh:mm:ss")).arg(tr(" received massage: ")).arg(RecvMsg);

    ui->tEdit_Recv_unicast->append(currentMsgstr);
}

void Widget::OnAutoSendData()
{
    qDebug() << "enter "<< __FUNCTION__ <<__LINE__;
    AppConfig *config = AppConfig::Instance();
    if(config == nullptr){
        return;
    }
    switch(config->CastType()){
    case BroadCast_type:
        on_pBtn_Send_clicked();
        break;
    case MutiCast_type:
        on_pBtn_Send_muticast_clicked();
        break;
    case UniCast_type:
        on_pBtn_Send_unicast_clicked();
        break;
    default:
        qDebug() << "castType error" << config->CastType();
        break;
    }
    qDebug() << "leave "<< __FUNCTION__ <<__LINE__;
}


void Widget::on_pBtn_Send_clicked()
{
    QByteArray sendArray;
    QString textStr = ui->tEdit_Send->toPlainText();
    if(!textStr.isEmpty()){
        AppController *pController = AppController::Instance();
        if(pController == nullptr){
            return;
        }
        //发送广播时作为Server端
        ui->label_ClientOrServer->setText(tr("Broadcast Server"));
        if(ui->checkBox_IfHexSend->checkState() == Qt::Checked){
            QString hexStr = AsciiToHex(textStr);
            sendArray = hexStr.toUtf8();
        }else{
            sendArray = textStr.toUtf8();
        }
        pController->SendData(sendArray);
        //发送广播完成清空
        ui->label_ClientOrServer->setText(tr(""));
    }
}

void Widget::on_pBtn_ClearRecv_clicked()
{
    QString recvStr = ui->tEdit_Recv->toPlainText();
    if(!recvStr.isEmpty()){
        ui->tEdit_Recv->setText("");
    }
}


void Widget::on_lEdit_LocalPort_textEdited(const QString &arg1)
{
    ui->lEdit_TargetPort->setText(arg1);

    AppConfig* config = AppConfig::Instance();
    if(config == nullptr)
        return;
    config->SetBroadCastPort(arg1.toInt());
}



void Widget::on_lEdit_BroadcastAddr_textEdited(const QString &arg1)
{
    ui->lEdit_TargetAddr->setText(arg1);

    AppConfig* config = AppConfig::Instance();
    if (config == nullptr)
        return;

    config->SetBroadCastIP(arg1);
}


void Widget::on_pBtn_ClearSend_clicked()
{
    QString sendStr = ui->tEdit_Send->toPlainText();
    if(!sendStr.isEmpty()){
        ui->tEdit_Send->setText("");
    }
}


void Widget::on_checkBox_IfAutoSend_stateChanged()
{
     QByteArray sendStr = ui->tEdit_Send->toPlainText().toUtf8();     
    if(ui->checkBox_IfAutoSend->checkState() == Qt::Checked
            &&!sendStr.isEmpty()){
        int interval = ui->lEdit_Interval_autoSend->text().toInt();
        if(myTimer->isActive() == false){
            myTimer->start(interval);
        }

    }else{
        if(myTimer->isActive() == true){
            myTimer->stop();
        }
    }
}

void Widget::on_pBtn_Start_muticast_clicked()
{
    int ret = 0;
    AppController* controller = AppController::Instance();

    if (nullptr == controller)
        return;

    QString btnState = ui->pBtn_Start_muticast->property("state").toString();
    qDebug() << "btnState=" << btnState;
    if (btnState.isEmpty() || btnState == "stop")
    {

        ret = controller->StartController();
        if(ret == COMM_OK){
            ui->pBtn_Start_muticast->setProperty("state", "start");
            ui->pBtn_Start_muticast->setText(QObject::tr("stop"));
        }else{
            QString ErrMsg = getErroMsg(ret);
            QMessageBox msgbox;
            msgbox.setText(ErrMsg);
        }
    }
    else
    {
        ui->pBtn_Start_muticast->setProperty("state", "stop");
        ui->pBtn_Start_muticast->setText(QObject::tr("start"));
        controller->StopController();
    }
}


void Widget::on_pBtn_ClearRecv_muticast_clicked()
{
    if(!ui->tEdit_Recv_muticast->toPlainText().isEmpty()){
        ui->tEdit_Recv_muticast->setText("");
    }
}


void Widget::on_pBtn_ClearSend_muticast_clicked()
{
    if(!ui->tEdit_Send_Muticast->toPlainText().isEmpty()){
        ui->tEdit_Send_Muticast->setText("");
    }
}


void Widget::on_pBtn_Send_muticast_clicked()
{
    int ret = 0;
    QByteArray sendArray;
    QString textStr = ui->tEdit_Send_Muticast->toPlainText(); //toUtf8 QString 转QbyteArray    fromUtf8 QbyteArray转QString
    AppController *pController = AppController::Instance();
    if(pController == nullptr){
        return;
    }
    qDebug()<<"textStr="<<textStr<<__func__<<__LINE__;
    if(!textStr.isEmpty()){
        qDebug() << (ui->chkBox_hex_send_muticast->checkState()==Qt::Checked)<<__FUNCTION__ << __LINE__;
        if(ui->chkBox_hex_send_muticast->checkState()==Qt::Checked){
            QString hexSrc = AsciiToHex(textStr);
            sendArray = hexSrc.toUtf8();
        }else{
            sendArray = textStr.toUtf8();
        }
        ret = pController->SendData(sendArray);
        if(ret != COMM_OK){
            QString ErrInfo =  getErroMsg(ret);
            QMessageBox::critical(this,tr("warning"), ErrInfo);
        }else{
            QString statusMsg = QString("%1%2").arg(QDateTime::currentDateTime().toString("yyyy-mm-dd hh:mm:ss")).arg(": send message success.");
            ui->label_SendStatus_muticast->setText(statusMsg);
        }
        qDebug()<<"leave "<< __FUNCTION__<<__LINE__<< ret;
    }

}






void Widget::on_lEdit_localPort_muticast_textEdited(const QString &arg1)
{
    qDebug() << "arg1=" << arg1;
    AppConfig *config = AppConfig::Instance();
    if(config == nullptr){
        qDebug() << "no memory.";
        return;
    }
    int localPort_Muticast = ui->lEdit_LocalPort->text().toInt();
    config->setLocalPort_Muticast(localPort_Muticast);

}


void Widget::on_lEdit_TargetAddr_muticast_textEdited(const QString &arg1)
{
    qDebug()<<"arg1="<<arg1;
    AppConfig *config = AppConfig::Instance();
    if(config == nullptr){
        qDebug() << "no memory.";
        return;
    }
   // QString muticast_IPAddr = ui->lEdit_TargetAddr_muticast->text();
    ui->lEdit_muticastAddr->setText(arg1);
    config->setMutiCastIP(arg1);
}


void Widget::on_lEdit_TargetPort_muticast_textChanged(const QString &arg1)
{
    AppConfig *config = AppConfig::Instance();
    if(config == nullptr){
        qDebug() << "no memory.";
        return;
    }
    //int muticastPort = ui->lEdit_TargetPort_muticast->text().toInt();
    config->setMutiCastPort(arg1.toInt());
}


void Widget::on_lEdit_localIP_muticast_textEdited(const QString &arg1)
{
    AppConfig *config = AppConfig::Instance();
    if(config == nullptr){
        qDebug() << "no memory.";
        return;
    }
   // QString muticast_localIPAddr = ui->lEdit_LocalAddr->text();
    config->setMutiCastIP(arg1);
}



void Widget::on_chkBox_ifAutosend_muticast_stateChanged(int arg1)
{
    AppController::Instance()->ResetController();
    QByteArray sendStr = ui->tEdit_Send_Muticast->toPlainText().toUtf8();
   if(arg1 == Qt::Checked &&!sendStr.isEmpty()){
       int interval = ui->lEdit_interval_muticast->text().toInt();
       qDebug() << "interval=" <<interval<<myTimer->isActive();
       if(myTimer->isActive() == false){
           myTimer->start(interval);
       }

   }else{
      if(myTimer->isActive() == true){
          myTimer->stop();
      }
   }

}




void Widget::on_lEdit_localPort_unicast_textEdited()
{
   int nPort = ui->lEdit_localPort_unicast->text().toInt();
   AppConfig::Instance()->setLocalPort_UniCast(nPort);
}


void Widget::on_lEdit_TargetIpAddr_unicast_textChanged()
{
    QString IpAddr = ui->lEdit_TargetIpAddr_unicast->text();
    AppConfig::Instance()->setTargetIP_UniCast(IpAddr);
}


void Widget::on_lEdit_TargetPort_unicast_textChanged()
{
    int nPort = ui->lEdit_TargetPort_unicast->text().toInt();
    AppConfig::Instance()->setTargetPort_UniCast(nPort);
}


void Widget::on_pBtn_Send_unicast_clicked()
{
    QByteArray sendArray;
    QString textStr = ui->tEdit_Send_unicast->toPlainText();
    if(textStr.isEmpty()){
        qDebug() << "senddata is empty.";
        return;
    }
    if(ui->chkBox_IfHexSend_unicast->checkState() == Qt::Checked){          
          QString hexStr = AsciiToHex(textStr);
          sendArray = hexStr.toUtf8();
    }else{
        sendArray = textStr.toUtf8();
        qDebug() << "sendData:" <<sendArray;        
    }
    AppController::Instance()->SendData(sendArray);
}


void Widget::on_pBtn_Clear_Send_unicast_clicked()
{
    if(!ui->tEdit_Recv_unicast->toPlainText().isEmpty()){
        ui->tEdit_Recv_unicast->setText("");
    }
}


void Widget::on_chkBox_IfAutoSend_unicast_stateChanged()
{
    if(ui->chkBox_IfAutoSend_unicast->checkState() == Qt::Checked){
        int interval = ui->lEdit_Interval_unicast->text().toInt();
        if(!myTimer->isActive()){
            myTimer->start(interval);
        }
    }else{
        if(myTimer->isActive()){
            myTimer->stop();
        }
    }
}


void Widget::on_pBtn_Start_Unicast_clicked()
{
    int ret = 0;

    AppController *controller = AppController::Instance();
    if(nullptr == controller ){
        return;
    }
    QString btnState = ui->pBtn_Start_Unicast->property("state").toString();
    if(btnState.isEmpty() || btnState == "stop"){
        ret = controller->StartController();
        if(ret == COMM_OK){
            ui->pBtn_Start_Unicast->setProperty("state", "start");
            ui->pBtn_Start_Unicast->setText(QObject::tr("stop"));
        }else{
            QString ErrMsg = getErroMsg(ret);
            QMessageBox msgbox;
            msgbox.setText(ErrMsg);
        }
    }else{
        controller->StopController();
        ui->pBtn_Start_Unicast->setProperty("state", "stop");
        ui->pBtn_Start_Unicast->setText(QObject::tr("start"));
    }
}


void Widget::on_pBtn_clearRecv_unicat_clicked()
{
    if(!ui->tEdit_Recv_unicast->toPlainText().isEmpty()){
        ui->tEdit_Recv_unicast->setText("");
    }
}

